import { UiFrameworkExtension, ConfigSpec } from '../../components'
import { Link } from '@brillout/docpress'

<ConfigSpec
  env="server"
  global={null}
/>

The `onRenderHtml()` hook defines how pages are rendered to HTML.

The hooks `onRenderHtml()` and <Link href="/onRenderClient">`onRenderClient()`</Link> are essentially the glue code between Vike and your UI framework (React/Vue/Solid/...).

> If you use a <UiFrameworkExtension />, then you don't need to (and shouldn't) define `onRenderHtml()` as it's already defined by <UiFrameworkExtension name noLink />.

```ts
// +onRenderHtml.ts
// Environment: server

export { onRenderHtml }

import type { PageContextServer } from 'vike/types'
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { renderToHtml, createElement } from 'some-ui-framework'

async function onRenderHtml(pageContext: PageContextServer){
  const { Page, data } = pageContext
  const pageHtml = await renderToHtml(createElement(Page, data))

  const documentHtml = escapeInject`<!DOCTYPE html>
    <html>
      <head>
        <title>My SSR App</title>
      </head>
      <body>
        <div id="page-root">${dangerouslySkipEscape(pageHtml)}</div>
      </body>
    </html>`

  return {
    documentHtml,
    pageContext: {
      // We can define pageContext values here
    }
  }
}
```

Where `pageContext.Page` is the <Link href="/Page">`+Page` value</Link> of the page that is being rendered.


## See also

- <Link href="/onRenderClient" />
- <Link href="/onAfterRenderHtml" />
- <Link href="/onBeforeRenderHtml" />
- <Link href="/hooks" />
- <Link href="/Page" />
- <Link href="/pageContext" />
